package com.zoffy.wmsbackend.utils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zoffy.wmsbackend.common.ErrorCode;
import com.zoffy.wmsbackend.exception.BusinessException;
import com.zoffy.wmsbackend.mapper.StockMapper;
import com.zoffy.wmsbackend.model.entity.*;
import com.zoffy.wmsbackend.service.StockService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Component
public class StockUtil {
    @Resource
    private StockMapper stockMapper;
    @Resource
    private StockService stockService;
    public synchronized void addStock(List<StockInOrderDetail> stockInOrderDetails){

        if(stockInOrderDetails==null || stockInOrderDetails.isEmpty()){
            return;
        }
        List<Long> goodsIdList = stockInOrderDetails.stream().map(StockInOrderDetail::getGoodsId).toList();
        List<Stock> stockList = stockMapper.getStockByGoodIdsAndWarehouseId(goodsIdList, stockInOrderDetails.get(0).getWarehouseId());
        Map<Long, Stock> stockMap = stockList.stream().collect(Collectors.toMap(Stock::getGoodsId, stock -> stock));
        stockInOrderDetails.forEach(stockInOrderDetail -> {
            Stock stock = stockMap.get(stockInOrderDetail.getGoodsId());
            if(stock==null){
                stock=new Stock();
                stock.setWarehouseId(stockInOrderDetail.getWarehouseId());
                stock.setGoodsId(stockInOrderDetail.getGoodsId());
                stock.setQuantity(0);
            }
            stock.setQuantity(stock.getQuantity()+stockInOrderDetail.getQuantity());
            stockMap.put(stockInOrderDetail.getGoodsId(),stock);
        });
        List<Stock> stocks = stockMap.values().stream().toList();
        stockService.saveOrUpdateBatch(stocks);
    }
    public synchronized void subStock(List<StockOutOrderDetail> stockOutOrderDetails){

        if(stockOutOrderDetails==null || stockOutOrderDetails.isEmpty()){
            return;
        }
        List<Long> goodsIdList = stockOutOrderDetails.stream().map(StockOutOrderDetail::getGoodsId).toList();
        List<Stock> stockList = stockMapper.getStockByGoodIdsAndWarehouseId(goodsIdList, stockOutOrderDetails.get(0).getWarehouseId());
        Map<Long, Stock> stockMap = stockList.stream().collect(Collectors.toMap(Stock::getGoodsId, stock -> stock));
        stockOutOrderDetails.forEach(stockInOrderDetail -> {
            Stock stock = stockMap.get(stockInOrderDetail.getGoodsId());
            if(stock==null){
                stock=new Stock();
                stock.setWarehouseId(stockInOrderDetail.getWarehouseId());
                stock.setGoodsId(stockInOrderDetail.getGoodsId());
                stock.setQuantity(0);
            }
            if(stock.getQuantity()<stockInOrderDetail.getQuantity()){
                throw new BusinessException(ErrorCode.OPERATION_ERROR,"库存不足: "+stockInOrderDetail.getStockOutDetailNo());
            }
            stock.setQuantity(stock.getQuantity()-stockInOrderDetail.getQuantity());
            stockMap.put(stockInOrderDetail.getGoodsId(),stock);
        });
        List<Stock> stocks = stockMap.values().stream().toList();
        stockService.saveOrUpdateBatch(stocks);
    }

    public void transferStock(StockTransferOrder transferOrder, List<StockTransferOrderDetail> transferOrderDetails) {
        Long originWarehouseId = transferOrder.getOriginWarehouseId();
        Long targetWarehouseId = transferOrder.getTargetWarehouseId();

        // 提取所有商品 ID
        List<Long> goodsIds = transferOrderDetails.stream()
                .map(StockTransferOrderDetail::getGoodsId)
                .collect(Collectors.toList());

        // 批量查询源仓库和目标仓库的库存
        Map<Long, Stock> originStockMap = getStockMap(originWarehouseId, goodsIds);
        Map<Long, Stock> targetStockMap = getStockMap(targetWarehouseId, goodsIds);

        // 准备需要更新和插入的库存列表
        List<Stock> originStocksToUpdate = new ArrayList<>();
        List<Stock> targetStocksToUpdate = new ArrayList<>();
        List<Stock> targetStocksToInsert = new ArrayList<>();

        for (StockTransferOrderDetail detail : transferOrderDetails) {
            Long goodsId = detail.getGoodsId();
            Integer quantity = detail.getQuantity();

            // 源仓库扣减库存
            Stock originStock = originStockMap.get(goodsId);
            if (originStock == null || originStock.getQuantity() < quantity) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "源仓库库存不足");
            }
            originStock.setQuantity(originStock.getQuantity() - quantity);
            originStocksToUpdate.add(originStock);

            // 目的仓库增加库存
            Stock targetStock = targetStockMap.get(goodsId);
            if (targetStock == null) {
                targetStock = new Stock();
                targetStock.setWarehouseId(targetWarehouseId);
                targetStock.setGoodsId(goodsId);
                targetStock.setQuantity(quantity);
                targetStocksToInsert.add(targetStock);
            } else {
                targetStock.setQuantity(targetStock.getQuantity() + quantity);
                targetStocksToUpdate.add(targetStock);
            }
        }

        // 批量更新和插入库存信息
        if (!originStocksToUpdate.isEmpty()) {
            stockService.updateBatchById(originStocksToUpdate);
        }
        if (!targetStocksToUpdate.isEmpty()) {
            stockService.updateBatchById(targetStocksToUpdate);
        }
        if (!targetStocksToInsert.isEmpty()) {
            stockService.saveBatch(targetStocksToInsert);
        }
        
    }
    private Map<Long, Stock> getStockMap(Long warehouseId, List<Long> goodsIds) {
        if(goodsIds==null||goodsIds.isEmpty()){
            return new HashMap<>();
        }
        LambdaQueryWrapper<Stock> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(Stock::getWarehouseId, warehouseId)
                .in(Stock::getGoodsId, goodsIds);
        List<Stock> stocks = stockMapper.selectList(queryWrapper);
        return stocks.stream()
                .collect(Collectors.toMap(Stock::getGoodsId, stock -> stock));
    }
}
